# -*- coding: UTF-8 -*-

import re
from datetime import datetime
import sys
from sqlalchemy import and_,  func, or_
from typing import Dict, List, Any, Generator

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, DECIMAL, FLOAT
from sqlalchemy.orm import Session, relationship
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger

from app.service_quality.models.qos_host_disk import QosHostDisk


__all__ = ['QosHostInfo']

class QosHostInfo(Base, SessionMixin):
    '''
    主机的信息
    '''
    __tablename__ = "qos_host_info"
    quality_date = Column(String(64), nullable=False, index=True, comment='数据日期')
    instance_id = Column(String(128), nullable=False, index=True, comment='实例ID')
    name = Column(String(128), nullable=False, index=True, comment='主机名')
    ip = Column(String(24), nullable=False, index=True,comment='ip地址')
    cpu = Column(Integer, nullable=False, default=0, comment='cpu配置单位核')
    mem = Column(Integer, nullable=False, default=0, comment='内存配置单位G')
    tag = Column(String(64), nullable=False, comment='主机标签')
    instance_charge_type = Column(String(128), nullable=False, comment='主机付费类型')
    instance_price = Column(DECIMAL(10,2), nullable=False, comment='主机价格')
    # Running开机、Top关机
    status = Column(String(16), nullable=False, comment='主机状态')
    cloud_platform = Column(String(64), nullable=False, comment='云平台')
    account_name = Column(String(128), nullable=False, comment='账号名称')
    
    environment = Column(String(128), nullable=False,  comment='环境')
    maintain_department = Column(String(128), nullable=False, comment='管理部门')
    belong_department = Column(JSON, nullable=False, comment='所属部门')
    classes = Column(String(128), nullable=False, comment='主机归类')
    job_number = Column(String(128), comment='关联工单号')
    applicant = Column(String(128), comment='资源申请人')
    owner = Column(String(128), comment='资源归属人')
    create_time = Column(DateTime, comment="创建时间")
    expire_time = Column(DateTime, comment="过期时间")
    update_at = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    comment = Column(String(256), nullable=True, comment='备注说明')



    __table_args__ = (
        Index('idx_qos_host_info_quality_date_name_ip', 'quality_date', 'name', 'ip', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic'
        }
    )

    def __repr__(self):
        return f"<qos_service_info='{self.name}>"


    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        
        result["disks_info"] = QosHostDisk.get_info_by_host_instance_id(db, result["quality_date"], result["instance_id"])
        
        return result


    @classmethod
    def get_object_by_instance_id(cls, db: Session, quality_date: str, instance_id: str):
        object = db.query(cls).filter(
            cls.quality_date == quality_date,
            cls.instance_id == instance_id
        ).first()
        return object


    @classmethod
    def get_info_by_instance_id(cls, db: Session, quality_date: str, instance_id: str):
        object = cls.get_object_by_instance_id(db, quality_date, instance_id)
        if not object:
            object_info = {}
        else:
            object_info = {
                "name": object.name,
                "ip": object.ip
            }
        return object_info
    
    
    # 删除一个日期所有的数据，重新入库
    @classmethod
    def delete_by_quality_date(cls, db: Session, quality_date: str):
        db.query(cls).filter(
            cls.quality_date == quality_date
        ).delete()
        db.commit()
        
        
        
    
    # 日期内，根据field字段模糊查询value
    @classmethod
    def get_host_info_search(cls, db: Session, quality_date: str, page: int, per_page: int, field: str, value: str):
        try:
            search_field = []
            display_field = cls.get_display_field()
            if value or field != "all":
                for key, col in cls.__table__.c.items():
                    if field == "all" or key == field:
                        search_field.append(col.like(f"%{value}%"))

            result = db.query(cls).filter(
                cls.quality_date == quality_date,
                or_(*search_field)
            ).with_entities(
                *display_field
            ).paginate(page=page, per_page=per_page)
        except Exception as e:
            logger.exception(f'{sys._getframe().f_code.co_name} {e}')
            return None

        # 每个字段的说明
        result["fields"] = cls.get_display_field_meta()

        return result
